package com.ruoyi.ams.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.ams.domain.vo.AssetAddVo;
import com.ruoyi.ams.domain.vo.AssetEditVo;
import com.ruoyi.ams.domain.vo.SaveAmsAssetInfoBatchVo;
import com.ruoyi.ams.service.*;
import com.ruoyi.common.core.domain.AssetInfoView;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.AmsAssetInfo;
import com.ruoyi.common.core.domain.model.AmsAssetType;
import com.ruoyi.common.core.domain.model.AmsOwnAsset;
import com.ruoyi.common.core.domain.model.ImportAssetInfoVo;
import com.ruoyi.common.core.domain.vo.DoImportAssetInfoVo;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.security.annotation.PreAuthorize;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * 资产基础信息Controller
 *
 * @author yfkj
 * @date 2021-10-15
 */
@RestController
@RequestMapping("/ams/AmsAssetInfo")
public class AmsAssetInfoController extends BaseController {
    @Autowired
    private IAssetInfoViewService assetInfoViewService;
    @Autowired
    private IAmsAssetInfoService amsAssetInfoService;
    @Autowired
    private IAmsAssetTypeService amsAssetTypeService;
    @Autowired
    private IAmsAssetBrandService amsAssetBrandService;
    @Autowired
    private IAmsAssetProjectService amsAssetProjectService;
    @Autowired
    private IAmsOwnAddressService amsOwnAddressService;
    @Autowired
    private IAmsAssetTemplateService amsAssetTemplateService;
    @Autowired
    private IAmsOwnAssetService amsOwnAssetService;
    @Autowired
    private AmsAsyncService amsAsyncService;

    @GetMapping("/getAmsUserName")
    public String getAmsUserName(){
        String userName = SecurityUtils.getUsername();
        return userName;
    }
    /**
     * 查询资产基础信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetInfo:list")
    @GetMapping("/list")
    @ApiOperation("资产查询展示列表")
    public TableDataInfo list(AmsAssetInfo amsAssetInfo) {
        boolean admin = SecurityUtils.isAdmin(SecurityUtils.getUserId());

        if (!admin) {

        }

        startPage();
        List<AmsAssetInfo> list = amsAssetInfoService.selectAmsAssetInfoList(amsAssetInfo);
        return getDataTable(list);
    }

    /**
     * 导出资产基础信息列表
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetInfo:export")
    @Log(title = "资产基础信息", businessType = BusinessType.EXPORT)
    @PostMapping(value="/export", produces = "application/octet-stream")
    public void export(HttpServletResponse response, AmsAssetInfo amsAssetInfo) throws IOException {
        List<AmsAssetInfo> list = amsAssetInfoService.selectAmsAssetInfoList(amsAssetInfo);
        ExcelUtil<AmsAssetInfo> util = new ExcelUtil<AmsAssetInfo>(AmsAssetInfo.class);
        util.exportExcel(response, list, "资产基础信息数据");
    }

    /**
     * 获取资产基础信息详细信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetInfo:query")
    @GetMapping(value = "/{assetId}")
    public AjaxResult getInfo(@PathVariable("assetId") Long assetId) {
        return AjaxResult.success(amsAssetInfoService.selectAmsAssetInfoByAssetId(assetId));
    }

    /**
     * 新增资产基础信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetInfo:add")
    @Log(title = "资产基础信息", businessType = BusinessType.INSERT)
    @PostMapping(value = "/addAsset")
    public AjaxResult addAsset(@RequestBody AssetAddVo assetAddVo) {
        AmsAssetInfo amsAssetInfo = new AmsAssetInfo();
        BeanUtils.copyProperties(assetAddVo, amsAssetInfo);
        return toAjax(amsAssetInfoService.insertAmsAssetInfo(amsAssetInfo));
    }

    /**
     * 修改资产基础信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetInfo:edit")
    @Log(title = "资产基础信息", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/editAsset")
    public AjaxResult editAsset(@RequestBody AssetEditVo assetEditVo) {
        AmsAssetInfo amsAssetInfo = new AmsAssetInfo();
        BeanUtils.copyProperties(assetEditVo, amsAssetInfo);
        return toAjax(amsAssetInfoService.updateAmsAssetInfo(amsAssetInfo));
    }

    /**
     * 删除资产基础信息
     */
    @PreAuthorize
    //@PreAuthorize(hasPermi = "ams:AmsAssetInfo:remove")
    @Log(title = "资产基础信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{assetIds}")
    public AjaxResult remove(@PathVariable Long[] assetIds) {
        return toAjax(amsAssetInfoService.deleteAmsAssetInfoByAssetIds(assetIds));
    }


    @PostMapping("/assetInfoCheckTypeAndCode")
    @PreAuthorize

    public R<Map<String, AmsAssetType>> assetInfoCheckTypeAndCode(@RequestParam("typeNames") Set<String> typeNames,
                                                                  @RequestParam("codes") Set<String> codes
                                                 ) {

        Map<String, AmsAssetType> resultMap = new HashMap<>();
        //数据检查
        StringBuilder stringBuilder = new StringBuilder();
        boolean isOk=true;
        if(codes.size()>0){
            List<AmsAssetInfo> assetInfos =amsAssetInfoService.list(new QueryWrapper<AmsAssetInfo>().in(AmsAssetInfo.SN,codes));
            if(assetInfos.size()>0){
                stringBuilder.append("以下资产编码已存在，请排除！");
                stringBuilder.append("\n");
                assetInfos.forEach(item -> stringBuilder.append(item.getSn()).append("\n"));
                isOk=false;
            }

        }
        List<AmsAssetType> types = amsAssetTypeService.list(new QueryWrapper<AmsAssetType>().in(AmsAssetType.ASSET_TYPE_NAME,typeNames).groupBy(AmsAssetType.ASSET_TYPE_NAME));
        if (typeNames.size() != types.size()) {
            List<String> hasTypes = new ArrayList<>();
            types.forEach(item -> hasTypes.add(item.getAssetTypeName()));
            typeNames.removeAll(hasTypes);
            stringBuilder.append("以下资产类型名称不存在，请先添加！");
            stringBuilder.append("\n");
            typeNames.forEach(item -> stringBuilder.append(item).append("\n"));
            isOk=false;
        }else {
            Map<Long, AmsAssetType> typeIdTypeMap = new HashMap<>();
            types.forEach(item->{
                typeIdTypeMap.put(item.getAssetTypeId(),item);
                resultMap.put(item.getAssetTypeName(),item);
            });
            List<AmsAssetType> checkTypes = amsAssetTypeService.list(new QueryWrapper<AmsAssetType>().in(AmsAssetType.PARENT_ID,typeIdTypeMap.keySet()).groupBy(AmsAssetType.PARENT_ID));
            if(checkTypes.size()>0){
                isOk=false;
                stringBuilder.append("以下资产类型名称是上级类型名称，请选择最下级的类型名称！");
                stringBuilder.append("\n");
                checkTypes.forEach(item -> stringBuilder.append(typeIdTypeMap.get(item.getParentId()).getAssetTypeName()).append("\n"));
            }

        }
        return isOk? R.ok(resultMap): R.fail(stringBuilder.toString());
    }
    @PostMapping("/importAssetInfo")
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public R<ImportAssetInfoVo> importAssetInfo(@RequestBody DoImportAssetInfoVo vo, @RequestParam("xid")String xid){

        ImportAssetInfoVo resultVo =new ImportAssetInfoVo();
        String userName = SecurityUtils.getUsername();
        amsAsyncService.getProjects(resultVo,vo.getProjectNames(),userName);
        amsAsyncService.getBrands(resultVo,vo.getBrandNames(),userName);
        amsAsyncService.getTypeAndTemplate(resultVo,vo.getTypeMap(),vo.getTypeNames(),userName);
        return R.ok(resultVo);
    }

    @PostMapping("/saveAmsAssetInfoBatch")
    @Transactional
    public R<Map<Integer, AssetInfoView>> saveAmsAssetInfoBatch(@RequestBody List<SaveAmsAssetInfoBatchVo> vos){

        Map<Integer, AssetInfoView> resultMap =new HashMap<>();
        Set<Long> assetIds= new HashSet<>();
        List<AmsAssetInfo> assetInfos =new ArrayList<>();
        for (SaveAmsAssetInfoBatchVo vo : vos) {
            assetInfos.add(vo.getAssetInfo());
        }
        amsAssetInfoService.saveBatch(assetInfos);
        List<AmsOwnAsset> ownAssets =new ArrayList<>();
        for (SaveAmsAssetInfoBatchVo vo : vos) {
            AmsOwnAsset ownAsset = vo.getOwnAsset();
            ownAsset.setAssetId(vo.getAssetInfo().getAssetId());
            assetIds.add(ownAsset.getAssetId());
            ownAssets.add(ownAsset);
        }
        amsOwnAssetService.saveBatch(ownAssets);
        Map<Long, AssetInfoView> allMap =new HashMap<>();
        List<AssetInfoView> list = assetInfoViewService.list(new QueryWrapper<AssetInfoView>().in(AssetInfoView.ASSET_ID, assetIds));
        list.forEach(item->allMap.put(item.getAssetId(),item));
        for (SaveAmsAssetInfoBatchVo vo : vos) {
            resultMap.put(vo.getIndex(), allMap.get(vo.getAssetInfo().getAssetId()));
        }
        return R.ok(resultMap);
    }
}
